package com.ymk.cmd;

import cn.hutool.core.util.IdUtil;
import com.ymk.base.cmd.ACmd;
import com.ymk.base.cmd.CmdSign;
import com.ymk.base.exception.MallException;
import com.ymk.base.utlis.ParamsBuilder;
import com.ymk.bo.goods.GoodsBO;
import com.ymk.bo.goods.GoodsCartBO;
import com.ymk.bo.orders.OrdersBO;
import com.ymk.bo.orders.OrdersItemBO;
import com.ymk.core.code.cmd.GoodsCmdCode;
import com.ymk.core.code.cmd.OrdersCmdCode;
import com.ymk.core.constants.SysConstants;
import com.ymk.core.enums.orders.OrdersItemStatusEnum;
import com.ymk.core.enums.orders.OrdersStatusEnum;
import com.ymk.service.IOrdersItemService;
import com.ymk.service.IOrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
public class OrdersPostCmd extends ACmd {

    @Override
    public CmdSign executeStore(HttpServletRequest request, CmdSign sign) throws Exception {
        CmdSign respSign = new CmdSign(sign);
        OrdersBO reqData = super.getData(sign, OrdersBO.class);
        ParamsBuilder paramsBuilder = ParamsBuilder.newBuild()
                .addParam("idList", reqData.getCartIdList());
        // 获取购物车数据
        CmdSign cartCmd = CmdSign.Builder.newBuild(sign)
                .setSource(paramsBuilder.build())
                .setCmdCode(GoodsCmdCode.GOODS_CART_LIST)
                .setScope(SysConstants.CMD_SERVER_SCOPE)
                .build();
        List<GoodsCartBO> goodsCartBOList = this.scheduler.schedule(request, cartCmd, GoodsCartBO.class, true);
        if (Objects.isNull(goodsCartBOList) || goodsCartBOList.isEmpty()) {
            throw new MallException("购物车数据异常");
        }

        //组成商品子数据
        Integer goodsCount = 0;
        List<OrdersItemBO> ordersItemBOList = new ArrayList<>();
        for (GoodsCartBO goodsCartBO : goodsCartBOList) {
            paramsBuilder.clearParam()
                    .addParam("id", goodsCartBO.getGoodsId());
            CmdSign goodsCmd = CmdSign.Builder.newBuild(sign)//?
                    .setSource(paramsBuilder.build())
                    .setCmdCode(GoodsCmdCode.GOODS_GET)
                    .setScope(SysConstants.CMD_SERVER_SCOPE)
                    .build();
            GoodsBO goodsBO = this.scheduler.schedule(request, goodsCmd, GoodsBO.class);

            OrdersItemBO ordersItemBO = new OrdersItemBO();
            ordersItemBO.setMchId(sign.getMchId());
            ordersItemBO.setMemberId(sign.getUserId());
            ordersItemBO.setGoodsId(goodsBO.getId());
            ordersItemBO.setSkuId(goodsCartBO.getSkuId());
            ordersItemBO.setSkuName(goodsCartBO.getSkuName());
            ordersItemBO.setAmount(goodsBO.getPrice());
            ordersItemBO.setGoodsCount(goodsCartBO.getGoodsCount());
            ordersItemBO.setTotalAmount(goodsBO.getPrice().multiply(new BigDecimal(goodsCartBO.getGoodsCount())));
            ordersItemBO.setRemark(goodsCartBO.getRemark());

            goodsCount = goodsCount + goodsCartBO.getGoodsCount();
            ordersItemBOList.add(ordersItemBO);
        }

        // 计算价格
        BigDecimal sumAmount = ordersItemBOList.stream().map(OrdersItemBO::getTotalAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // 组装订单数据
        OrdersBO ordersBO = new OrdersBO();
        ordersBO.setMchId(sign.getMchId());
        ordersBO.setDeskId(reqData.getDeskId());
        ordersBO.setOrderNo(IdUtil.simpleUUID());
        ordersBO.setMemberId(sign.getUserId());
        ordersBO.setOrdersAmount(sumAmount);
        ordersBO.setPayAmount(sumAmount);
        ordersBO.setSubOrderCount(ordersItemBOList.size());
        ordersBO.setGoodsCount(goodsCount);
        ordersBO.setRemark(reqData.getRemark());
        ordersBO.setStatus(OrdersStatusEnum.UNPAID.getStatus());
        super.setCreatedData(sign, ordersBO);

        this.ordersService.post(ordersBO);

        // 订单子数据入库
        ordersItemBOList.forEach(ordersItemBO -> {
            ordersItemBO.setOrdersId(ordersBO.getId());
            ordersItemBO.setStatus(OrdersItemStatusEnum.UNPAID.getStatus());
            super.setCreatedData(sign, ordersItemBO);
            this.ordersItemService.post(ordersItemBO);
        });

        // 清空购物车
        paramsBuilder.clearParam()
                .addParam("idList", reqData.getCartIdList());
        CmdSign delCmd = CmdSign.Builder.newBuild(sign)
                .setSource(paramsBuilder.build())
                .setCmdCode(GoodsCmdCode.GOODS_CART_DEL)
                .setScope(SysConstants.CMD_SERVER_SCOPE)
                .build();
        this.scheduler.schedule(request, delCmd);

        respSign.setSource(super.getSource(ordersBO));
        return respSign;
    }

    @Override
    public String getCmdCode() {
        return OrdersCmdCode.ORDERS_POST;
    }

    @Autowired
    private IOrdersService ordersService;
    @Autowired
    private IOrdersItemService ordersItemService;
}